package org.jeecg.modules.device.controller;

import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.*;


import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.util.JsonUtils;
import org.jeecg.common.util.UUIDGenerator;
import org.jeecg.modules.device.entity.Device;
import org.jeecg.modules.device.service.IDeviceService;
import org.jeecg.modules.order.entity.Order;
import org.jeecg.modules.order.service.IOrderService;
import org.jeecg.modules.system.service.ISysDictService;
import org.jeecg.modules.system.util.RC4Util;
import org.jeecg.modules.zixishi.entity.Quyu;
import org.jeecg.modules.zixishi.entity.Seat;
import org.jeecg.modules.zixishi.entity.Zixishi;
import org.jeecg.modules.zixishi.service.IQuyuService;
import org.jeecg.modules.zixishi.service.ISeatService;
import org.jeecg.modules.zixishi.service.IZixishiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;


@RestController
@RequestMapping("/menjin")
@Slf4j
public class MenJinController {

    @Autowired
    private ISeatService seatService;
    @Autowired
    private IQuyuService quyuService;
    @Autowired
    private IZixishiService zixishiService;
    @Autowired
    private IDeviceService deviceService;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private ISysDictService sysDictService;

    //新版协议(6.0开头的版本)，将心跳与远程接口合并为一个，即为QueryCmd
    @RequestMapping(value = "/QueryCmd", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")//访问地址与请求方法，
    public String QueryCmd(@RequestBody String params) { //获取body里的json数据并返回在body里·
        StringBuilder sb = new StringBuilder();
        try {
            //接收到的数据格式  {"ViewId":"1","UID":"123","UKey":"1234","SN":"170000001","TamperAlarm":"0","DoorMagnetic":"0","Timestamp":"1594198847962","Sign":"1fcc27459b99d16ee5ba2dc6e657d5c8"}
            sb.append(URLDecoder.decode(params, "UTF-8"));
            if (sb.length() > 11 && sb.substring(0, 11).equals("paramaters=")) //旧接口协议有前缀，判断一下，去掉
                sb.delete(0, 11); //去掉paramaters=
//            log.info("QueryCmd:" + sb);
            //解析json
            JSONObject json = JSON.parseObject(sb.toString());

            String viewId = json.getString("ViewId");
            String uid = json.getString("UID");
            String uKey = json.getString("UKey");
            String sn = json.getString("SN");//卡号
            String tamperAlarm = json.getString("TamperAlarm");
            String doorMagnetic = json.getString("DoorMagnetic");

            Device device = deviceService.getOne(new LambdaQueryWrapper<Device>().eq(Device::getUid,uid));
            if(device == null){
                device = new Device();
                device.setDeviceName(uid).setUid(uid).setViewId(viewId).setUkey(uKey).setDoorMagnetic(tamperAlarm).setDoorMagnetic(doorMagnetic).setCmdCode("0");
                deviceService.save(device);
            }
            if(StringUtils.isBlank(device.getCmdCode())){
                device.setCmdCode("0");
            }
            //返回数据
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            int CmdCode = Integer.parseInt(device.getCmdCode());
            String CmdID = UUIDGenerator.generate();// String.valueOf(System.currentTimeMillis());//CmdID可定义

            JSONObject jsonObj = new JSONObject();
            JSONObject jsonObjCmd0 = new JSONObject();
            jsonObjCmd0.put("DateTime", formatter.format(new Date()));//返回服务器时间给设备
            jsonObj.put("CmdID", CmdID);
            jsonObj.put("CmdCode", CmdCode);
            jsonObj.put("CmdParams", jsonObjCmd0);

            String ret = jsonObj.toJSONString(); //无命令返回格式：{"CmdCode":0,"CmdID":"1601193461935","CmdParams":{"DateTime":"2020-09-27 15:57:41"}}
//            log.info("Return QueryCmd:" + ret);
            return ret;

        } catch (Exception e) {
            //e.printStackTrace();
            log.info("Ex:" + e.getMessage());
        }
        return "";
    }

    @RequestMapping(value = "/QueryCmdPostData", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String QueryCmdPostData(@RequestBody String params) { //获取body里的json数据并返回在body里·
        StringBuilder sb = new StringBuilder();
        try {
            //接收到的数据格式  {"CodeVal":"985","CodeType":"Q","BrushTime":"2020-09-24 09:17:21","ViewId":"1","UID":"123","UKey":"1234","SN":"170000001","IsOnline":"1","Property":"1","Timestamp":"1600910241600","Sign":"ed097d71179890af524759daacaea06f"}
            sb.append(URLDecoder.decode(params, "UTF-8"));
            if (sb.length() > 11 && sb.substring(0, 11).equals("paramaters=")) //旧接口协议有前缀，判断一下，去掉
                sb.delete(0, 11); //去掉paramaters=
            log.info("QueryCmdPostData:" + sb);
            //解析json

            JSONObject json = JSON.parseObject(sb.toString());
            String viewId = json.getString("ViewId");
            String uid = json.getString("UID");
            String uKey = json.getString("UKey");
            String sn = json.getString("SN");//卡号
            String cmdId = json.getString("CmdID");
            Integer cmdCode = json.getInteger("CmdCode");
            Integer cmdStatus = json.getInteger("CmdStatus");
            String cmdParams = json.getString("CmdParams");

            Integer respStatus = 0;
            Device device = deviceService.getOne(new LambdaQueryWrapper<Device>().eq(Device::getUid,uid));;
            if(null != device){
                respStatus = 1;
                if(1 == cmdStatus){
                    if(4 == cmdCode || 1 == cmdCode){
                        Device d = new Device();
                        d.setId(device.getId()).setCmdCode("0");
                        deviceService.updateById(d);
                    } else {
                        log.info("cmdCode:" + cmdCode);
                    }
                }
            }

            //返回数据
            JSONObject jsonObj = new JSONObject();
            jsonObj.put("Status", respStatus);
            jsonObj.put("StatusDesc","");
            String ret = jsonObj.toJSONString();
            return ret;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
            log.error("Ex:" + e.getMessage());
        }
        return "";
    }

    //定义一个验证接口
    @RequestMapping(value = "/CheckCode", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")//访问地址与请求方法
    public String CheckCode(@RequestBody String params) { //获取body里的json数据并返回在body里·
        StringBuilder sb = new StringBuilder();
        try {
            //接收到的数据格式  {"CodeVal":"985","CodeType":"Q","BrushTime":"2020-09-24 09:17:21","ViewId":"1","UID":"123","UKey":"1234","SN":"170000001","IsOnline":"1","Property":"1","Timestamp":"1600910241600","Sign":"ed097d71179890af524759daacaea06f"}
            sb.append(URLDecoder.decode(params, "UTF-8"));
            if (sb.length() > 11 && sb.substring(0, 11).equals("paramaters=")) //旧接口协议有前缀，判断一下，去掉
                sb.delete(0, 11); //去掉paramaters=
            log.info("CheckCode:" + sb);
            //解析json
            JSONObject json = JSON.parseObject(sb.toString());
            String viewId = json.getString("ViewId");
            String uid = json.getString("UID");
            String uKey = json.getString("UKey");
            String sn = json.getString("SN");//卡号

            String codeVal = json.getString("CodeVal"); //[ordernum,view1|view2,starttime,endtime]
            String codeType = json.getString("CodeType");
            String brushTime = json.getString("BrushTime");
            String isOnline = "1";//json.getString("IsOnline");
            String property = json.getString("Property");
            String oriValue = codeVal;
            Integer respStatus = 0;
            String respDesc = "";

            if(StringUtils.equals("1",isOnline)) {

                try {
                    codeVal = StringUtils.substring(codeVal, 4);
                    codeVal = RC4Util.decry_RC4(codeVal);
                    codeVal = StringUtils.substring(codeVal, 1, codeVal.length() - 1);
                    log.info("codeVal:" + codeVal);
                    String[] codes = codeVal.split(",");
                    String orderNum = codes[0];

                    Order order = orderService.getOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNum,orderNum));
                    if(null != order){
                        String orderStatus = order.getOrderStatus();
                        Date startTime = order.getStartTime();
                        Date endTime = order.getEndTime();
                        if(StringUtils.equals("1",orderStatus)|| StringUtils.equals("2",orderStatus)){

                            Seat seat = seatService.getById(order.getSeatId());
                            Quyu quyu = quyuService.getById(order.getQuyuId());
                            Zixishi zixishi = zixishiService.getById(order.getZixishiId());

                            Set<String> devices = new HashSet<>();
                            String devStr = "";
                            devStr = StringUtils.isNotBlank(seat.getDevices())?devStr + "," + seat.getDevices():devStr;
                            devStr = StringUtils.isNotBlank(quyu.getDevices())?devStr + "," + quyu.getDevices():devStr;
                            devStr = StringUtils.isNotBlank(zixishi.getDevices())?devStr + "," + zixishi.getDevices():devStr;
                            String[] dvs = StringUtils.split(devStr, ",");
                            if (null != dvs && dvs.length > 0) {
                                for (String dv : dvs) {
                                    devices.add(dv);
                                }
                            }
                            if(devices.contains(uid)) {
                                if (startTime.getTime() <= new Date().getTime() && endTime.getTime() >= new Date().getTime()) {
                                    Integer s = Integer.parseInt(DateUtil.format(startTime, "HHmmss"));
                                    Integer e = Integer.parseInt(DateUtil.format(endTime, "HHmmss"));
                                    if (e == 0) {
                                        e = 235959;
                                    }
                                    Integer now = Integer.parseInt(DateUtil.format(new Date(), "HHmmss"));
                                    if (s <= now && e >= now) {
                                        respStatus = 1;
                                        respDesc = "验证成功\r\n请进";
                                    } else {
                                        respDesc = "不在当日时间范围";
                                    }
                                }else{
                                    respDesc = "不在订单时间范围";
                                }
                            }else{
                                respDesc = "无权限\r\n请核实";
                            }
                        }else{
                            respDesc = "订单状态:"+orderStatus + "\n请核实";
                        }
                    }else{
                        respDesc = "订单不存在\r\n请查询";
                    }

                    try{
                        if(1 != respStatus) {
                            List<DictModel> configs = sysDictService.getDictItems("menjin_admin");
                            if (null != configs && configs.size() > 0) {
                                Set<String> adminVals = new HashSet<>();
                                for (DictModel dictModel : configs) {
                                    adminVals.add(dictModel.getValue());
                                }

                                if (adminVals.contains(oriValue)) {
                                    respStatus = 1;
                                    respDesc = "管理员刷卡";
                                }
                            }
                        }
                    }catch (Exception ex){
                        log.error("Ex:" + ex.getMessage());
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                    log.error("Ex:" + e.getMessage());
                }
            }else{
                //TODO 离线记录，记录日志
            }

            //返回数据
            JSONObject jsonObj = new JSONObject();
            jsonObj.put("Status", respStatus); //1 合法 0 非法
            jsonObj.put("StatusDesc", respDesc);
//            jsonObj.put("Relay1Time", 1000);
//            jsonObj.put("TurnGateTimes", 1);
            //jsonObj.put("TTS","验票成功");

            String ret = jsonObj.toJSONString(); //返回格式：{"Status":1,"StatusDesc":"验票成功\r\n请进","TurnGateTimes":1,"Relay1Time":1000}
            log.info("Return CheckCode:" + ret);
            return ret;

        } catch (Exception e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
            log.info("Ex:" + e.getMessage());
        }
        return "";
    }

    @RequestMapping(value = "/CheckCodeWalkPast", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String CheckCodeWalkPast(@RequestBody String params) { //获取body里的json数据并返回在body里·
        StringBuilder sb = new StringBuilder();
        try {
            //接收到的数据格式  {"CodeVal":"985","CodeType":"Q","BrushTime":"2020-09-24 09:17:21","ViewId":"1","UID":"123","UKey":"1234","SN":"170000001","IsOnline":"1","Property":"1","Timestamp":"1600910241600","Sign":"ed097d71179890af524759daacaea06f"}
            sb.append(URLDecoder.decode(params, "UTF-8"));
            if (sb.length() > 11 && sb.substring(0, 11).equals("paramaters=")) //旧接口协议有前缀，判断一下，去掉
                sb.delete(0, 11); //去掉paramaters=
            log.info("CheckCodeWalkPast:" + sb);
            //解析json
            JSONObject json = JSON.parseObject(sb.toString());
            String SN = json.getString("SN");//卡号
            //......以下写业务逻辑
            //................

            //返回数据
            JSONObject jsonObj = new JSONObject();
            jsonObj.put("Status", 0);

            String ret = jsonObj.toJSONString(); //返回格式：{"Status":0}
            log.info("Return CheckCodeWalkPast:" + ret);
            return ret;

        } catch (Exception e) {
            // TODO Auto-generated catch block
            //e.printStackTrace();
            log.info("Ex:" + e.getMessage());
        }
        return "";
    }
}
